package org.btik.lightweb.client;


import jakarta.websocket.*;
import jakarta.websocket.server.ServerEndpoint;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.btik.context.AppContext;
import org.btik.context.event.SystemStartHook;
import org.btik.light.meta.exception.LightException;
import org.btik.lightweb.paser.WebCmdParser;
import org.btik.light.meta.base.Command;
import org.btik.light.meta.base.DevRpcServer;
import org.springframework.stereotype.Service;



import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author lustre
 * @version 1.0
 * @since 2021/5/15 12:37
 * 控制台
 */
@ServerEndpoint("/control")
@Service
public class WebSockControl implements SystemStartHook {

    private static DevRpcServer rpcServer;

    private final Log log = LogFactory.getLog(WebSockControl.class);
    private static final Map<String, Session> CLIENTS = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session) {
        log.info("on open:" + session.getId());
        //将新用户存入在线的组
        CLIENTS.put(session.getId(), session);

    }


    @OnClose
    public void onClose(Session session) {
        log.info("on web socket close:" + session.getId());
        //将掉线的用户移除在线的组里
        CLIENTS.remove(session.getId());
    }


    @OnError
    public void onError(Throwable throwable) {
        log.info("on error:", throwable);
        if (log.isDebugEnabled()) {
            log.debug("", throwable);
        }
    }

    @OnMessage
    public void onMessage(String message, Session session) {

        try {
            Command parse = WebCmdParser.parse(message);
            rpcServer.sendCmd(parse);
        } catch (LightException le) {
            session.getAsyncRemote().sendText(le.getMessage());
        } catch (Exception e) {
            session.getAsyncRemote().sendText("server error");
        }


    }

    public void close(String sessionId) {
        Session session = CLIENTS.remove(sessionId);
        try {
            if (session != null) {
                session.close();
            }
        } catch (IOException e) {
            log.info("", e);
        }

    }

    public synchronized void sendAll(String message) {
        try {
            CLIENTS.forEach((k, v) -> {
                if (v.isOpen()) {
                    try {
                        v.getBasicRemote().sendText(message);
                    } catch (IOException e) {
                        log.error(e);
                    }
                } else {
                    close(k);
                }
            });
        } catch (IllegalStateException e) {
            log.error(e);
        } catch (Exception e) {
            log.error("", e);
        }

    }


    @Override
    public void onSystemStart(AppContext appContext) {
        WebSockControl.rpcServer = appContext.getBean(DevRpcServer.class);
    }
}
